import 'package:demo/constants/route_location.dart';
import 'package:demo/example/drag_example.dart';
import 'package:demo/example/example_dialog_activity.dart';
import 'package:demo/example/exmaple_list.dart';
import 'package:demo/example/fade_animation_list.dart';
import 'package:demo/example/material_design_animation_page.dart';
import 'package:demo/example/number_keyboard_example.dart';
import 'package:demo/example/pip_example.dart';
import 'package:demo/example/refresh_list.dart';
import 'package:demo/pages/guide_page.dart';
import 'package:demo/pages/root_page.dart';
import 'package:demo/pages/splash_page.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

enum RouteStyle {
  /// 安卓风格的跳转页面
  Android,

  /// ios风格的跳转页面
  IOS,

  /// 自定义跳转
  Custom,
}

class RouteApplication {
  /// 工厂模式
  factory RouteApplication() => _getInstance();

  /// 单例
  static RouteApplication get instance => _getInstance();
  static RouteApplication? _instance;

  RouteApplication._internal();

  static RouteApplication _getInstance() => _instance ??= RouteApplication._internal();

  /// 获取路由组
  Page<dynamic> getRoute(
    String path, {
    Map<String, dynamic>? params,
    RouteStyle style = RouteStyle.IOS,
    RouteTransitionsBuilder? customTransitionsBuilder,
  }) {
    Widget child;
    switch (path) {
      // 根getRoute
      case ROOT_LOCATION:
        child = RootPage();
        break;

      // 引导页
      case GUIDE_LOCATION:
        child = GuidePage();
        break;

      // 例子列表
      case EXAMPLE_LIST:
        child = ExampleList();
        break;
      // 安卓风格页面
      case EXAMPLE_MD_STYLE_LOCATION:
        child = MaterialDesignAnimationPage();
        break;
      // fade list效果
      case EXAMPLE_FADE_STYLE_LIST_LOCATION:
        child = FadeAnimationList();
        break;
      // 下拉刷新列表
      case EXAMPLE_REFRESH_LOCATION:
        child = RefreshList();
        break;
      // pip案例
      case EXAMPLE_PICTURE_IN_PICTURE:
        child = PIPExample();
        break;

      /// 数字键盘
      case NUMBER_KEYBOARD_EXAMPLE:
        child = NumberKeyboardExample();
        break;

      // 拖拽
      case EXAMPLE_DRAG:
        child = DragExample();
        break;

      case SPLASH_LOCATION:
        child = SplashPage();
        break;

      case EXAMPLE_DIALOG:
        child = ExampleDialogActivityPage();
        break;

      /// 断言child不能为空
      default:
        throw Exception("please check your page widget");
    }

    /// 确认一下是否自定义风格还是对应的平台对应的动画
    switch (style) {

      /// 安卓风格
      case RouteStyle.Android:
        return _getAndroidStylePageRoute(path, child, params);

      /// ios风格
      case RouteStyle.IOS:
        return _getIOSStylePageRoute(path, child, params);

      /// 自定动画路由
      case RouteStyle.Custom:
        return CustomPage(
          child: child,
          name: path,
          arguments: params,
          transitionsBuilder: customTransitionsBuilder!,
        );
    }
  }

  /// 获取安卓风格的页面路由跳转效果
  MaterialPage _getAndroidStylePageRoute(String path, Widget child, Object? arguments) =>
      MaterialPage(name: path, child: child, arguments: arguments);

  /// 获取安卓风格的页面路由跳转效果
  CupertinoPage _getIOSStylePageRoute(String path, Widget child, Object? arguments) =>
      CupertinoPage(name: path, child: child, arguments: arguments);
}

/// 自定义动画对应类
class CustomPage<T> extends Page<T> {
  /// 自定义页面构造器
  const CustomPage({
    required this.child,
    required this.transitionsBuilder,
    this.maintainState = true,
    this.fullscreenDialog = false,
    LocalKey? key,
    String? name,
    Object? arguments,
    String? restorationId,
  }) : super(key: key, name: name, arguments: arguments, restorationId: restorationId);

  /// 自定义的pageRoute
  final Widget child;

  /// 是否自动释放内存,与其他系统平台的一致
  final bool maintainState;

  /// 是否全屏,与其他系统平台的一致
  final bool fullscreenDialog;

  /// 动画构建
  final RouteTransitionsBuilder transitionsBuilder;

  @override
  Route<T> createRoute(BuildContext context) {
    return PageRouteBuilder<T>(
      settings: this,
      pageBuilder: (BuildContext _, Animation<double> animation, Animation<double> secondaryAnimation) => child,
      transitionsBuilder: (
        BuildContext context,
        Animation<double> animation,
        Animation<double> secondaryAnimation,
        Widget child,
      ) {
        return transitionsBuilder(context, animation, secondaryAnimation, child);
      },
    );
  }
}
